// https://blog.csdn.net/GFCLJY/article/details/140191204(win11下vscode编译运行cpp设置)
#include <iostream>

struct ListNode
{
    int val;
    ListNode *next;
    ListNode():val(0), next(nullptr){}
    ListNode(int x):val(x), next(nullptr){}
    ListNode(int x, ListNode *next):val(x), next(next){}
};
//* 第一种方法：先删头节点，再删非头节点
ListNode* removeElements1(ListNode* head, int val) {
    //删除头节点
    while (head != nullptr && head->val == val)
    {
        ListNode* tmp = head;
        head = head->next;
        delete tmp;
    }

    //删除非头节点
    ListNode* current_node = head;
    while(current_node != nullptr && current_node->next != nullptr)
    {
        if (current_node->next->val == val)
        {
            ListNode* tmp = current_node->next;
            current_node->next = current_node->next->next;
            delete tmp;
        }
        else
        {
            current_node = current_node->next;
        }
    }
    return head;
}

//* 第二种方法：删除链表中值为val的所有节点，并返回头节点
ListNode *removeElements2(ListNode *head, int val)
{
    ListNode *dummyNode = new ListNode(0);//引入虚拟节点
    dummyNode->next = head;//将虚拟节点作为头节点
    ListNode *current_node = dummyNode;
    while (current_node->next != nullptr)
    {
        if (current_node->next->val == val)
        {
            ListNode *tmp = current_node->next;
            current_node->next = current_node->next->next;
            delete tmp;
        }
        else
        {
            current_node = current_node->next;
        }
    }
    head = dummyNode->next;
    delete dummyNode;
    return head;
}

void OutPutListNodeVal(ListNode *head)
{
    std::cout<<"[";
    ListNode *cur_node = head;
    while (cur_node != nullptr)
    {
        std::cout<<cur_node->val;
        cur_node = cur_node->next;
        if (cur_node != nullptr)
        {
            std::cout<<", ";
        }
    }
    std::cout<<"]."<<std::endl;
}

void TestCase1()
{
    //case 1
    // 输入：head = [1,2,6,3,4,5,6], val = 6
    // 输出：[1,2,3,4,5]
    ListNode *case1_node0 = new ListNode(1);
    ListNode *case1_node1 = new ListNode(2);
    ListNode *case1_node2 = new ListNode(6);
    ListNode *case1_node3 = new ListNode(3);
    ListNode *case1_node4 = new ListNode(4);
    ListNode *case1_node5 = new ListNode(5);
    ListNode *case1_node6 = new ListNode(6);
    case1_node0->next = case1_node1;
    case1_node1->next = case1_node2;
    case1_node2->next = case1_node3;
    case1_node3->next = case1_node4;
    case1_node4->next = case1_node5;
    case1_node5->next = case1_node6;

    ListNode *head = removeElements1(case1_node0, 6);
    // ListNode *head = removeElements2(case1_node0, 6);
    // output
    OutPutListNodeVal(head);
}

void TestCase2()
{
    //case 2
    // 输入：head = [], val = 1
    // 输出：[]
    ListNode *case2_node0 = nullptr;
    ListNode *head = removeElements1(case2_node0, 1);
    // ListNode *head = removeElements2(case2_node0, 1);
    // output
    OutPutListNodeVal(head);
}

void TestCase3()
{
    //case 3
    // 输入：head = [7,7,7,7], val = 7
    // 输出：[]
    ListNode *case3_node0 = new ListNode(7);
    ListNode *case3_node1 = new ListNode(7);
    ListNode *case3_node2 = new ListNode(7);
    ListNode *case3_node3 = new ListNode(7);
    case3_node0->next = case3_node1;
    case3_node1->next = case3_node2;
    case3_node2->next = case3_node3;
    ListNode *head = removeElements1(case3_node0, 7);
    // ListNode *head = removeElements2(case3_node0, 7);
    // output
    OutPutListNodeVal(head);
}



int main()
{
    TestCase1();
    TestCase2();
    TestCase3();
    return 0;
}